package com.ccnf.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.ccnf.core.bean.StatusCode;
import com.ccnf.core.exception.BizException;
import com.ccnf.core.utils.ResultUtil;
import com.ccnf.core.utils.SystemClock;
import com.ccnf.model.entity.*;
import com.ccnf.model.mapper.*;
import com.ccnf.model.pojo.InvitationDetail;
import com.ccnf.model.pojo.InvitationReferenceVo;
import com.ccnf.service.InvitationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class InvitationServiceImpl extends ServiceImpl<InvitationMapper, Invitation> implements InvitationService {
    @Autowired
    private InvitationMapper invitationMapper;
    @Autowired
    private InvitationRecordMapper invitationRecordMapper;
    @Autowired
    private InvitationUserMapper invitationUserMapper;
    @Autowired
    private InvitationReportMapper invitationReportMapper;
    @Autowired
    private InvitationRewardMapper invitationRewardMapper;

    @Override
    @Transactional
    public Long save(Invitation invitation) {
        Long referenceId = invitation.getReferenceId();
        ResultUtil.validateSQL(invitationMapper.insert(invitation), "邀请函新增失败");
        Long invitationId = invitation.getInvitationId();
        if (referenceId != null) {
            invitationRecordMapper.incrementUseCount(referenceId);// 增加引用的邀请函使用次数加1
            invitationReportMapper.incrementUseCount(referenceId, SystemClock.zeroSecond());
        } else {
            Invitation updateInvitation = new Invitation();
            updateInvitation.setInvitationId(invitationId);
            updateInvitation.setReferenceId(invitationId);
            ResultUtil.validateSQL(invitationMapper.updateById(updateInvitation), "邀请函新增失败");
        }
        // 增加邀请函统计记录表数据
        InvitationRecord invitationRecord = new InvitationRecord();
        invitationRecord.setInvitationId(invitationId);
        ResultUtil.validateSQL(invitationRecordMapper.insert(invitationRecord), "邀请函新增失败");
        invitationRecord.setRecordType(1);
        ResultUtil.validateSQL(invitationRecordMapper.insert(invitationRecord), "邀请函新增失败");
        return invitationId;
    }

    @Override
    public void modify(Invitation invitation) {
        Long invitationId = invitation.getInvitationId();
        Invitation selectInvitation = invitationMapper.selectById(invitationId);// 查询邀请函信息
        ResultUtil.validateNull(selectInvitation, "没有找到该邀请函信息");
        Integer status = selectInvitation.getStatus();// 获取邀请函状态
        if (status == 3) {
            // 删除状态
            throw new BizException("该邀请函已经删除，不能更新操作");
        }
        if (!selectInvitation.getUserId().equals(invitation.getUserId())) {
            throw new BizException(StatusCode.NO_PERMISSION, "你没有权限修改");
        }
        Integer modifyStatus = invitation.getStatus();// 需要修改邀请函状态
        if (modifyStatus != null) {
            switch (modifyStatus) {
                case 0:
                    // 初始状态，未发布状态，用于从回收站恢复
                case 1:
                    invitation.setPublishTime(SystemClock.second());
                case 2:
                    invitation.setDeleteTime(SystemClock.second());
                case 3:
                    // 删除状态，用于删除回收站邀请函
                    if (selectInvitation.getIsMoney() == 1) {
                        // 赏金邀请函
                        InvitationReward selectInvitationReward = new InvitationReward();
                        selectInvitationReward.setInvitationId(invitationId);
                        InvitationReward updateInvitationReward = new InvitationReward();
                        updateInvitationReward.setIsDeleted(1);
                        invitationRewardMapper.update(updateInvitationReward, new EntityWrapper<>(selectInvitationReward));
                    }
                    break;
                default:
                    if (status == 2) {
                        // 该邀请函是回收站状态
                        throw new BizException("该邀请函已经放入回收站，不能更新操作");
                    }
                    if (modifyStatus == 1) {
                        // 发布状态
                        invitation.setPublishTime(SystemClock.second());// 设置邀请函发布时间
                    }
            }
        }
        ResultUtil.validateSQL(invitationMapper.updateById(invitation), "邀请函更新失败");
    }

    @Override
    public Invitation findBasicById(Long invitationId) {
        return baseMapper.selectBasicByInvitationId(invitationId);
    }

    @Override
    public Page<Invitation> findPersonalWithPage(Long expoId, Long userId, Page page) {
        return page.setRecords(invitationMapper.selectPersonalByUserId(page, expoId, userId));
    }

    @Override
    public Page<InvitationDetail> findCollectionWithPage(Long expoId, Long userId, Page page) {
        return page.setRecords(invitationMapper.selectCollectionByUserId(page, expoId, userId));
    }

    @Override
    public Page<Invitation> findTrashWithPage(Long expoId, Long userId, Page page) {
        return page.setRecords(invitationMapper.selectTrashByUserId(page, expoId, userId));
    }

    @Override
    public SocialUser findUserInfoByInvitationId(Long invitationId) {
        return invitationMapper.selectUserInfoByInvitationId(invitationId);
    }

    @Override
    public Invitation findDetailByUserIdAndInvitationId(Long invitationId, Long userId) {
        Invitation invitation = baseMapper.selectById(invitationId);
        ResultUtil.validateNull(invitation, "该邀请函不存在");
        Integer status = invitation.getStatus();
        if (status == 1) {
            // 邀请函是发布的
            handleInvitationUserBrowseRecord(invitationId, userId);
        } else if (status == 2){
            // 邀请函已删除
            throw new BizException(801, "该邀请函不可查看");
        } else if (!invitation.getUserId().equals(userId)) {
            // 不是邀请函创建人
            // 该邀请函未发布
            throw new BizException(801, "该邀请函不可查看");
        }
        return invitation;
    }

    @Override
    public void handleInvitationUserBrowseRecord(Long invitationId, Long userId) {
        InvitationUser selectInvitationUser = new InvitationUser();// 查询数据的过滤条件参数
        selectInvitationUser.setInvitationId(invitationId);
        selectInvitationUser.setUserId(userId);
        InvitationUser select = invitationUserMapper.selectOne(selectInvitationUser);// 查询邀请函和用户关联信息
        long zeroSecond = SystemClock.zeroSecond();// 当日的零点时间戳（秒）
        if (select == null) {
            selectInvitationUser.setBrowseTime(SystemClock.second());// 设置邀请函浏览时间
            ResultUtil.validateSQL(invitationUserMapper.insert(selectInvitationUser), "邀请函用户关联失败");

            handleInvitationCensus(invitationId, zeroSecond);
        } else {
            if (select.getBrowseTime() < zeroSecond) {
                handleInvitationCensus(invitationId, zeroSecond);
            }
            selectInvitationUser.setShareId(select.getShareId());
            selectInvitationUser.setBrowseTime(SystemClock.second());// 设置邀请函浏览时间
            ResultUtil.validateSQL(invitationUserMapper.updateById(selectInvitationUser), "用户最新浏览时间更新失败");
        }
    }

    private void handleInvitationCensus(Long invitationId, long zeroSecond) {
        new Thread(() -> {
            invitationRecordMapper.incrementBrowseCount(invitationId);// 增加总浏览和今日浏览次数
            // 增加邀请函每日报表统计
            InvitationReport invitationReport = new InvitationReport();
            invitationReport.setInvitationId(invitationId);
            invitationReport.setCreateTime(zeroSecond);
            InvitationReport selectInvitationReport = invitationReportMapper.selectOne(invitationReport);
            if (selectInvitationReport == null) {
                invitationReport.setBrowseCount(1);
                invitationReport.setUpdateTime(SystemClock.second());
                invitationReportMapper.insert(invitationReport);
            } else {
                invitationReportMapper.incrementBrowseCount(invitationId, zeroSecond);// 增加邀请函今日报表数据
            }
        }).start();
    }

    @Override
    public Page<InvitationDetail> findTemplateWithPage(Page page, Long expoId, String invitationTitle) {
        return page.setRecords(baseMapper.selectTemplateByUserId(page, expoId, invitationTitle));
    }

    @Override
    public InvitationDetail findLatestByUserId(Long expoId, Long userId) {
        return baseMapper.selectLatestByUserId(expoId, userId);
    }

    @Override
    public Page<InvitationReferenceVo> findPublishByUserId(Long expoId, Long userId, Page page) {
        return page.setRecords(baseMapper.selectPublishByUserId(expoId, userId, page));
    }

    @Override
    public Page<InvitationReferenceVo> findMoneyByUserId(Long expoId, Long userId, Page page) {
        return page.setRecords(baseMapper.selectMoneyByUserId(expoId, userId, page));
    }

    @Override
    public Page<InvitationReferenceVo> findReferenceByUserId(Long expoId, Long userId, Page page) {
        return page.setRecords(baseMapper.selectReferenceByUserId(expoId, userId, page));
    }

    @Override
    public Page<InvitationReferenceVo> findAuthByUserId(Long expoId, Long userId, Page page) {
        return page.setRecords(baseMapper.selectAuthByUserId(expoId, userId, page));
    }

    @Override
    public int findIsReferenceByInvitationIdAndUserId(Long invitationId, Long userId) {
        return baseMapper.selectIsReferenceByInvitationIdAndUserId(invitationId, userId);
    }
}